home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / datecls.exe / DATECLS4.CPP < prev    next >
C/C++ Source or Header  |  1993-03-07  |  12KB  |  626 lines

  1. /*
  2.  *┌──────────────────────────────────────────────────────────────────────
  3.  *│ File.........: DATECLS4.CPP
  4.  *│ Date.........: Sunday 3/7/1993
  5.  *│ Author.......: Kenneth A. Argo (CIS 71241,3635)
  6.  *│ Copyright....: None! Use freely.
  7.  *│ Version......: 4.1    Compile w/MSC++ 7.0
  8.  *│ Usage........: General purpose date conversion, arithmetic,
  9.  *│         :    comparison, and formatting class
  10.  *│
  11.  *│ See DATE.H for acknowledgements and compile/link notes.
  12.  *└──────────────────────────────────────────────────────────────────────
  13.  */
  14.  
  15. #include "datecls4.h"
  16.  
  17. int Date::DisplayFormat=MDY;
  18.  
  19. unsigned char Date::DisplayOptions='\0';
  20.  
  21. const char *dayname[] = {"Sunday","Monday","Tuesday","Wednesday",
  22.        "Thursday","Friday","Saturday"} ;
  23.  
  24. const char *mname[] = {"January","February","March","April","May",
  25.        "June","July","August","September","October","November","December"};
  26.  
  27. static int GauDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  28.  
  29. ////////////////////////////////////////////////////////////
  30. // Constructors
  31. ////////////////////////////////////////////////////////////
  32.  
  33. Date::Date()
  34. {
  35.     month = day = day_of_week = 0;
  36.     year = 0;
  37.     julian = 0;
  38. }
  39.  
  40. Date::Date (const long j) : julian(j)
  41. {
  42.     julian_to_mdy ();
  43. }
  44.  
  45. Date::Date (const int m, const int d, const int y) : month((unsigned char)m), day((unsigned char)d), year(y)
  46. {
  47.     mdy_to_julian ();
  48. }
  49.  
  50. Date::Date (char *dat)
  51. {
  52.     if (!_stricmp(dat, "TODAY"))
  53.     {
  54.         struct _dosdate_t temp_date;
  55.         _dos_getdate(&temp_date);
  56.         month = temp_date.month;
  57.         day   = temp_date.day;
  58.         year  = temp_date.year;
  59.     }
  60.     else
  61.     {
  62.         month = (unsigned char)atoi(strtok(dat,"/-"));
  63.         day   = (unsigned char)atoi(strtok(NULL,"/-"));
  64.         year  = atoi(strtok(NULL," "));
  65.     }
  66.  
  67.     mdy_to_julian ();
  68. }
  69.  
  70. Date::Date (const _dosdate_t &ds)
  71. {
  72.     month = ds.month;
  73.     day   = ds.day;
  74.     year  = ds.year;
  75.     mdy_to_julian ();
  76. }
  77.  
  78. Date::Date (const Date &dt)
  79. {
  80.     month = dt.month;
  81.     day   = dt.day;
  82.     year  = dt.year;
  83.     mdy_to_julian ();
  84. }
  85.  
  86. Date::~Date()
  87. {
  88.     if (buf != (char *)&BadDate)
  89.         delete buf;
  90. }
  91.  
  92. //////////////////////////////////////////////////////////////
  93. // Conversion operations
  94. //////////////////////////////////////////////////////////////
  95.  
  96. Date::operator char *( void )
  97. {
  98.     buf = new char[13];
  99.  
  100.     if (day==0 || month==0 || year==0)
  101.         buf = (char *)&BadDate;
  102.     else
  103.         sprintf(buf,"%1d/%1d/%-4d",month,day,year);
  104.  
  105.     return buf;
  106. }
  107.  
  108. //////////////////////////////////////////////////////////////
  109. // Date Arithmetic
  110. //////////////////////////////////////////////////////////////
  111.  
  112. Date &Date::operator + (const long i)
  113. {
  114.     return Date(julian + i);
  115. }
  116.  
  117. Date &Date::operator + (const int i)
  118. {
  119.     return Date(julian + (long)i);
  120. }
  121.  
  122. Date &Date::operator - (const long i)
  123. {
  124.     return Date(julian - i);
  125. }
  126.  
  127. Date &Date::operator - (const int i)
  128. {
  129.     return Date(julian - (long)i);
  130. }
  131.  
  132. long Date::operator - (const Date &dt)
  133. {
  134.     return ( julian - dt.julian );
  135. }
  136.  
  137. Date &Date::operator += (const long i)
  138. {
  139.     julian += i;
  140.     julian_to_mdy();
  141.     return *this;
  142. }
  143.  
  144. Date &Date::operator -= (const long i)
  145. {
  146.     julian -= i;
  147.     julian_to_mdy();
  148.     return *this;
  149. }
  150.  
  151. Date &Date::operator ++()
  152. {
  153.     julian++;
  154.     julian_to_mdy();
  155.     return *this;
  156. }
  157.  
  158. Date &Date::operator ++(int)
  159. {
  160.     julian++;
  161.     julian_to_mdy();
  162.     return *this;
  163. }
  164.  
  165. Date &Date::operator --()
  166. {
  167.     julian--;
  168.     julian_to_mdy();
  169.     return *this;
  170. }
  171.  
  172. Date &Date::operator --(int)
  173. {
  174.     julian--;
  175.     julian_to_mdy();
  176.     return *this;
  177. }
  178.  
  179. //////////////////////////////////////////////////////////////
  180. // Date comparison
  181. //////////////////////////////////////////////////////////////
  182.  
  183. int operator <  (const Date &dt1, const Date &dt2)
  184. {
  185.     return ( dt1.julian < dt2.julian );
  186. }
  187.  
  188. int operator <= (const Date &dt1, const Date &dt2)
  189. {
  190.     return ( (dt1.julian == dt2.julian) || (dt1.julian < dt2.julian) );
  191. }
  192.  
  193. int operator >  (const Date &dt1, const Date &dt2)
  194. {
  195.     return ( dt1.julian > dt2.julian );
  196. }
  197.  
  198. int operator >= (const Date &dt1, const Date &dt2)
  199. {
  200.     return ( (dt1.julian == dt2.julian) || (dt1.julian > dt2.julian) );
  201. }
  202.  
  203. int operator == (const Date &dt1, const Date &dt2)
  204. {
  205.     return ( dt1.julian == dt2.julian );
  206. }
  207.  
  208. int operator != (const Date &dt1, const Date &dt2)
  209. {
  210.     return ( dt1.julian != dt2.julian );
  211. }
  212.  
  213. ////////////////////////////////////////////////////////////////
  214. // Ostream operations
  215. ////////////////////////////////////////////////////////////////
  216.  
  217. ostream &operator << (ostream &os, const Date &dt)
  218. {
  219.     return os << dt.formatDate();
  220. }
  221.  
  222. ostream &operator << (ostream &os, const _dosdate_t &dt)
  223. {
  224.     return os << (int)dt.month << "/" << (int)dt.day << "/" << dt.year;
  225. }
  226.  
  227. //////////////////////////////////////////////////////////////
  228. // Conversion routines
  229. //////////////////////////////////////////////////////////////
  230.  
  231. void Date::julian_to_wday (void)
  232. {
  233.     day_of_week = (unsigned char) ((julian + 2) % 7 + 1);
  234. }
  235.  
  236. void Date::julian_to_mdy ()
  237. {
  238.     long a,b,c,d,e,z,alpha;
  239.     z = julian+1;
  240.  
  241.     // dealing with Gregorian calendar reform
  242.  
  243.     if (z < 2299161L)
  244.         a = z;
  245.     else
  246.     {
  247.         alpha = (long) ((z-1867216.25) / 36524.25);
  248.         a = z + 1 + alpha - alpha/4;
  249.     }
  250.  
  251.     b = ( a > 1721423 ? a + 1524 : a + 1158 );
  252.     c = (long) ((b - 122.1) / 365.25);
  253.     d = (long) (365.25 * c);
  254.     e = (long) ((b - d) / 30.6001);
  255.  
  256.     day = (unsigned char)(b - d - (long)(30.6001 * e));
  257.     month = (unsigned char)((e < 13.5) ? e - 1 : e - 13);
  258.     year = (int)((month > 2.5 ) ? (c - 4716) : c - 4715);
  259.     julian_to_wday ();
  260. }
  261.  
  262. void Date::mdy_to_julian (void)
  263. {
  264.     int a,b=0;
  265.     int work_month=month, work_day=day, work_year=year;
  266.  
  267.     // correct for negative year
  268.  
  269.     if (work_year < 0)
  270.         work_year++;
  271.  
  272.     if (work_month <= 2)
  273.     {
  274.         work_year--;
  275.         work_month +=12;
  276.     }
  277.  
  278.     // deal with Gregorian calendar
  279.  
  280.     if (work_year*10000. + work_month*100. + work_day >= 15821015.)
  281.     {
  282.         a = (int)(work_year/100.);
  283.         b = 2 - a + a/4;
  284.     }
  285.  
  286.     julian = (long) (365.25*work_year) +
  287.              (long) (30.6001 * (work_month+1))  +  work_day + 1720994L + b;
  288.     julian_to_wday ();
  289. }
  290.  
  291. ////////////////////////////////////////////////////////////////
  292. // Format routine
  293. ////////////////////////////////////////////////////////////////
  294.  
  295. char *Date::formatDate (const int type) const
  296. {
  297.     static char buf[40];
  298.  
  299.     _strnset( buf, '\0', sizeof(buf) );
  300.  
  301.     switch ( type )
  302.     {
  303.         case DAY:
  304.  
  305.             if ( (day_of_week < 1) || (day_of_week > 7) )
  306.                 strcpy(buf,"invalid day");
  307.             else
  308.                 strncpy( buf, dayname[day_of_week-1],
  309.                     (DisplayOptions & DATE_ABBR) ? ABBR_LENGTH : 9);
  310.  
  311.             return buf;
  312.             break;
  313.  
  314.         case MONTH:
  315.  
  316.             if ( (month < 1) || (month > 12) )
  317.                 strcpy(buf,"invalid month");
  318.             else
  319.                 strncpy( buf, mname[month-1],
  320.                     (DisplayOptions & DATE_ABBR) ? ABBR_LENGTH : 9);
  321.  
  322.             return buf;
  323.             break;
  324.  
  325.         case FULL:
  326.  
  327.             if ( (month < 1) || (month > 12) || (day_of_week < 0) ||
  328.                  (day_of_week > 7) )
  329.             {
  330.                 strcpy(buf,"invalid date");
  331.                 return buf;
  332.             }
  333.  
  334.             strncpy( buf, dayname[day_of_week-1],
  335.                 (DisplayOptions & DATE_ABBR) ? ABBR_LENGTH : 9);
  336.             strcat( buf, ", ");
  337.             strncat( buf, mname[month-1],
  338.                 (DisplayOptions & DATE_ABBR) ? ABBR_LENGTH : 9);
  339.             strcat( buf, " ");
  340.             sprintf( buf+strlen(buf), "%d, %d", day, abs(year) );
  341.  
  342.             if (year < 0)
  343.                 strcat(buf," B.C.E.");
  344.  
  345.             return buf;
  346.             break;
  347.  
  348.         case EUROPEAN:
  349.  
  350.             if ( (month < 1) || (month > 12) || (day_of_week < 0) ||
  351.                  (day_of_week > 7) )
  352.             {
  353.                 strcpy(buf,"invalid date");
  354.                 return buf;
  355.             }
  356.  
  357.             sprintf(buf,"%d ",    day);
  358.             strncat(buf, mname[month-1],
  359.                 (DisplayOptions & DATE_ABBR) ? ABBR_LENGTH : 9);
  360.             sprintf( buf+strlen(buf), " %d", abs(year) );
  361.  
  362.             if (year < 0)
  363.                 strcat(buf," B.C.E.");
  364.  
  365.             return buf;
  366.             break;
  367.  
  368.         case MDY:
  369.  
  370.         default:
  371.             if (day==0 || month==0 || year==0)
  372.                 strcpy(buf,"invalid date");
  373.             else
  374.                 sprintf( buf+strlen(buf), "%1d/%1d/%02d", month, day,
  375.                     (DisplayOptions & NO_CENTURY) && (abs(year) > 1899)
  376.                     ? (abs(year) - (abs(year) / 100 * 100))
  377.                     : (abs(year))  );
  378.  
  379.             return buf;
  380.             break;
  381.     }
  382. }
  383.  
  384. void Date::setFormat( const int format )
  385. {
  386.     DisplayFormat = format;
  387. }
  388.  
  389. int Date::